package main

import (
	"fmt"
	"interface/mock"
	"interface/real"
	"time"
)

// 接口 Retriever
type Retriever interface {
	Get(url string) string // 默认函数，不能加func
}

type Poster interface {
	Post(url string, form map[string]string) string
}

type RetrieverPoster interface {
	Retriever
	Poster
}

func main() {

	// 调用 Retriever 接口
	var r Retriever
	r = mock.Retriever{Contents: "this is fake retriever"}

	r = &real.Retriever{
		UserAgent: "Mozilla/5.0",
		TimeOut:   time.Minute,
	}
	inspect(r)
	// fmt.Println(download(r))

	// 调用 复合接口, mock实现两个接口
	fmt.Println("try a session")
	mockRetriever := mock.Retriever{
		Contents: "this is a fake aqie home"}
	fmt.Println(session(&mockRetriever))
}

// 查看结构体r内参数类型
func inspect(r Retriever) {
	fmt.Printf(">%T %v\n", r, r)
	switch v := r.(type) {
	case mock.Retriever:
		fmt.Println("Contents:", v.Contents)
	case *real.Retriever:
		fmt.Println("UserAgent:", v.UserAgent)
	}

	// Type assertion, 查看interface内部内容
	if realRetriever, ok := r.(*real.Retriever); ok { // .(类型名)
		fmt.Println(realRetriever) // 取得结构体里面内容 / 地址
		fmt.Println(realRetriever.TimeOut)
	} else {
		fmt.Println("不是real.Retriever 类型!")
	}
}

const url = "http://www.baidu.com"

// Retriever 接口调用Get方法
func download(r Retriever) string {
	return r.Get(url)
}

// Poster 接口调用Post()方法
func post(post Poster) {
	post.Post(url, map[string]string{
		"name":   "ccmouse",
		"course": "golang",
	})
}

// 组合  Retriever 和 Poster接口
func session(s RetrieverPoster) string {
	s.Post(url, map[string]string{
		"contents": "another faked imooc.com", // 最终打印语句
	})
	return s.Get(url)
}
